package com.uvt.agenda.pdf;

import com.uvt.agenda.Event;
import com.uvt.agenda.EventsProvider;
import com.uvt.agenda.iterator.EIterator;
import android.content.Context;
import android.os.Environment;
import com.itextpdf.text.pdf.draw.VerticalPositionMark;
import com.uvt.agenda.EventsProvider;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.uvt.agenda.iterator.EventsContainer;


/**
 * Created with IntelliJ IDEA.
 * User: Cristi C
 * Date: 2/5/14
 * Time: 11:28 PM
 */
public class PdfBuilder implements Builder{

    private PdfCalendar instance;
    private EventsProvider eventsProvider;
    protected EventsContainer events;

    public PdfCalendar Build(Context context, EventsProvider eventsProvider) throws DocumentException, IOException{
        instance = new PdfCalendar(context);
        this.eventsProvider = eventsProvider;
        return instance;
    }

    public PdfPCell drawMonthHeader(Calendar calendar, Locale locale) {
        PdfPCell cell = new PdfPCell();
        cell.setColspan(7);
        cell.setBackgroundColor(BaseColor.WHITE);
        cell.setUseDescender(true);
        Paragraph p = new Paragraph(String.format(locale, "%1$tB %1$tY", calendar), instance.bold);
        p.setAlignment(Element.ALIGN_CENTER);
        cell.addElement(p);
        return cell;
    }

    public PdfPCell drawDayMonthHeader(Calendar calendar, Locale locale) {
        PdfPCell cell = new PdfPCell();
        cell.setBackgroundColor(BaseColor.WHITE);
        cell.setUseDescender(true);
        Paragraph p = new Paragraph(String.format(locale, "%1$td %1$tB %1$tY", calendar), instance.bold);
        p.setAlignment(Element.ALIGN_CENTER);
        cell.addElement(p);
        return cell;
    }

    public PdfPCell drawEventsCell(Calendar calendar, Locale locale, int year, int month, int day) {
        PdfPCell cell = new PdfPCell();
        cell.setBackgroundColor(BaseColor.WHITE);
        cell.setUseDescender(true);

        Chunk eventChunk = new Chunk();
        Chunk titleChunk = new Chunk();
        eventChunk.setFont(instance.small);
        titleChunk.setFont(instance.normal);


        events = eventsProvider.getEventsFor(year,month,day);
        EIterator iterator = events.getIterator();
        while (iterator.hasNext()){
            Event e = iterator.next();
            Paragraph title = new Paragraph(titleChunk);
            Paragraph ev = new Paragraph(eventChunk);
            title.add(new Chunk(e.getName()));
            ev.add(new Chunk(e.getDescription()));
            cell.addElement(title);
            cell.addElement(ev);
        }

        return cell;
    }

    public PdfPCell drawCellDay(Calendar calendar, Locale locale, float cellHeight, int year, int month, int day) {
        PdfPCell cell = new PdfPCell();
        cell.setFixedHeight(cellHeight);
        cell.setPadding(10);

        if (isSunday(calendar))
            cell.setBackgroundColor(BaseColor.GRAY);
        else if (isSpecialDay(calendar))
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
        else
            cell.setBackgroundColor(BaseColor.WHITE);

        Chunk chunk = new Chunk(String.format(locale, "%1$ta", calendar), instance.small);
        chunk.setTextRise(8);

        Chunk eventChunk = new Chunk();
        eventChunk.setFont(instance.small);

        Paragraph p = new Paragraph(chunk);
        p.add(new Chunk(new VerticalPositionMark()));
        p.add(new Chunk(calendar.get(Calendar.DAY_OF_MONTH) + "", instance.normal));

        // Print the first 4 events in the box;
        if(day>0 && month>0 && year>0){
            events = eventsProvider.getEventsFor(year,month,day);
        }
        else if(month>0 && year>0){
            events = eventsProvider.getEventsFor(year,month);
        }
        else if(year>0){
            events = eventsProvider.getEventsFor(year);
        }

        cell.addElement(p);
        EIterator iterator = events.getIterator();
        while (iterator.hasNext()){
            cell.setBackgroundColor(BaseColor.YELLOW);
            Event e = iterator.next();
            Paragraph ev = new Paragraph(eventChunk);
            ev.add(new Chunk(e.getName()));
            cell.addElement(ev);
        }

        return cell;
    }

    public boolean isSunday(Calendar calendar) {
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    public boolean isSpecialDay(Calendar calendar) {
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
            return true;
        return false;
    }

    public void createPDF(Locale locale, int year) throws IOException, DocumentException {
        Document document = new Document(PageSize.A4.rotate());
        File sdDir = Environment.getExternalStorageDirectory();

        String fileName = sdDir.getAbsoluteFile() + "/calendar-wholeYear.pdf";
        File myFile = new File(fileName);
        if(myFile.exists())
            myFile.delete();

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(sdDir.getAbsoluteFile() + "/calendar-wholeYear.pdf"));
        document.open();
        PdfPTable table;
        Calendar calendar;
        PdfContentByte canvas = writer.getDirectContent();

        for (int month = 0; month < 12; month++) {
            calendar = new GregorianCalendar(year, month-1, 1);
            table = new PdfPTable(7);
            table.setTotalWidth(document.getPageSize().getWidth() - 2 * document.rightMargin());

            table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
            table.addCell(drawMonthHeader(calendar, locale));
            int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            int day = 1;
            int position = 2;

            while (position != calendar.get(Calendar.DAY_OF_WEEK)) {
                position = (position % 7) + 1;
                table.addCell("");
            }

            while (day <= daysInMonth) {
                calendar = new GregorianCalendar(year, month-1, day);
                float cellHeight = (document.getPageSize().getHeight() - document.topMargin() - document.bottomMargin())/7;
                table.addCell(drawCellDay(calendar, locale, cellHeight, year,month,day));
                day++;
            }

            table.completeRow();

            table.writeSelectedRows(0, -1, document.leftMargin(), document.getPageSize().getHeight() - document.topMargin(), canvas);
            document.newPage();
        }
        document.close();
    }

    public void createPDF(Locale locale, int year, int month) throws IOException, DocumentException {
        Document document = new Document(PageSize.A4.rotate());
        File sdDir = Environment.getExternalStorageDirectory();

        String fileName = sdDir.getAbsoluteFile() + "/calendar_"+year+"_"+month+".pdf";
        File myFile = new File(fileName);
        if(myFile.exists())
            myFile.delete();

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(sdDir.getAbsoluteFile() + "/calendar_"+year+"_"+month+".pdf"));
        document.open();
        PdfPTable table;
        Calendar calendar;
        PdfContentByte canvas = writer.getDirectContent();

        calendar = new GregorianCalendar(year, month-1, 1);
        table = new PdfPTable(7);
        table.setTotalWidth(document.getPageSize().getWidth() - 2 * document.rightMargin());

        table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
        table.addCell(drawMonthHeader(calendar, locale));
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        int day = 1;
        int position = 2;

        while (position != calendar.get(Calendar.DAY_OF_WEEK)) {
            position = (position % 7) + 1;
            table.addCell("");
        }

        while (day <= daysInMonth) {
            calendar = new GregorianCalendar(year, month-1, day);
            float cellHeight = (document.getPageSize().getHeight() - document.topMargin() - document.bottomMargin())/7;
            table.addCell(drawCellDay(calendar, locale, cellHeight,year,month,day));
            day++;
        }

        table.completeRow();

        table.writeSelectedRows(0, -1, document.leftMargin(), document.getPageSize().getHeight() - document.topMargin(), canvas);
        document.newPage();
        document.close();
    }


    //TODO: To be completed
//
    public void createPDF(Locale locale, int year, int month, int day) throws IOException, DocumentException {

        Document document = new Document(PageSize.A4.rotate());
        File sdDir = Environment.getExternalStorageDirectory();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(sdDir.getAbsoluteFile() + "/calendar_"+year+"_"+month+"_"+day+".pdf"));
        document.open();
        PdfPTable table;
        Calendar calendar;
        PdfContentByte canvas = writer.getDirectContent();

        calendar = new GregorianCalendar(year, month-1, day);
        table = new PdfPTable(1);
        table.setTotalWidth(document.getPageSize().getWidth() - 2 * document.rightMargin());

        table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
        table.addCell(drawDayMonthHeader(calendar, locale));
        calendar = new GregorianCalendar(year, month-1, day);
        table.addCell(drawEventsCell(calendar, locale, year, month, day));

        table.completeRow();

        table.writeSelectedRows(0, -1, document.leftMargin(), document.getPageSize().getHeight() - document.topMargin(), canvas);
        document.newPage();
        document.close();
    }

}
